#include "UserLib\include\serial.h"
#include "UserLib\lib\MyMath.h"
#include "App/SerialCmd.h"
//#define DebugRawDate
#define DigitBytesCount 1
#define ChNoAll 0xff
#define Cmd_Error  0xEE
#define Cmd_Digit 0x60
#define Cmd_Analog 0x30
#define Cmd_Ver   0x30
#define CmdPos 4
#define SrcAddrPos 2
#define MinValidLen 5
#define ErrCode_UnKnowCmd 1
#define ChannelCount 4

const uint8 VerMessage[]={0x80+40,1,0,14,8,7};


void ADC_DMA(void);
void ADC_LowPower(void);
void ADC_Trigger(void);
void Time_Base(void);
void SerialPort_Init(int32 baud);
void GpioInit(void);
void SendAnalog(uint8 dstAddr,uint8 * attachData);
void SendDigit(uint8 dstAddr,uint8 *attachData);
void SendVer(uint8 dstAddr,uint8 *attachData);
void SendCmdError(uint8 dstAddr,uint8 errCode,void *errData,uint8 errDataLen);
uint8 ReadChannelVal(uint8 chNo,uint16 *retval);
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

uint16 ACValues[ChannelCount];
uint8  DigitValues[ChannelCount];
uint16 Coeff[ChannelCount];
uint8  devAddr=4;
VoltCalcer    calcers[ChannelCount];
uint16 Threshold[ChannelCount];
uint8  FactoryInfo[0x40];

void SerialCmdDeal();
void AdDataDeal();
void SetWorkLedOn();
void SetWorkLedOff();
void AnalogDeal();
void  CopyFactroyInfoToRam();
void SendFactroyInfo(uint8 dstAddr,uint8 *attachData);
uint8 SaveInfo(uint8 *buf,uint16 len);
void SetFactroyInfo(uint8 dstAddr,uint8 *attachData);
void UpdateCoeff();
uint8 ReadAddr();
void SetWorkLedOff();
void  SetWorkLedO();

int main(void)
{
    int i=0;
    int j=0; 
   //automatically added by CoIDE
	  GpioInit();


    devAddr = ReadAddr();
    devAddr = ReadAddr();


	//automatically added by CoIDE
    if(0!=(devAddr&0x80))
    {
  	  SerialPort_Init(19200);
    }
    else
    {
  	  SerialPort_Init(57600);
    }
    devAddr&=0x7f;
 //   Serial_SendArr(&devAddr,1);
	//automatically added by CoIDE
	Time_Base();


	//automatically added by CoIDE
	ADC_DMA();
	InitFrameDeal();
    

    SetRxAddr(devAddr);

    for(i=0;i<ChannelCount;i++)
    {

      Coeff[i]=3300;
      ACValues[i]=0;
      Threshold[i]=50;
    }
    CopyFactroyInfoToRam();
   	while(1)
    {
	    	SerialCmdDeal();
		    AnalogDeal();

    }
}
void CopyFactroyInfoToRam()
{
	int i;
	uint8 *srcAddr=(uint8 *)0x08003C00;
	for(i=0;i<0x40;i++)
	{
		FactoryInfo[i]=*srcAddr;
		srcAddr++;
	}
	UpdateCoeff();

}
void UpdateCoeff()
{
	int i;
	uint16 *coeffBaseAddr=(uint16 *)(FactoryInfo+0x20);
	for(i=0;i<ChannelCount;i++){
		coeffBaseAddr++;
		if((*coeffBaseAddr==0xffff)||(*coeffBaseAddr==0)){
			*coeffBaseAddr=0x1000;
		}
	    Coeff[i]=*coeffBaseAddr;
	    coeffBaseAddr++;
	}

}
static int ledState=0;
void SerialCmdDeal()
{
   DataFrame *rxFrame;
   rxFrame=RxCmd();
   if(rxFrame==NULL)
   {
     return;
   }

   if(ledState==0)
   {
	   ledState=1;
     SetWorkLedOn();
   }
   else
   {
	   ledState=0;
	 SetWorkLedOff();
   }
   if(rxFrame->Count<MinValidLen)
   {
     //SendCmdError();
     return;
   }

   int cmd=rxFrame->Data[CmdPos];

   uint8 srcAddr=rxFrame->Data[SrcAddrPos];
   uint8 *attachData = rxFrame->Data+5;
   switch(cmd)
   {
      case 0x30:
         SendAnalog(srcAddr,attachData);
         break;
      case 0x20:
         SendDigit(srcAddr,attachData);
         break;
      case 0xe2:
         SetFactroyInfo(srcAddr,attachData);
         break;
      case 0xe4:
    	 SendFactroyInfo(srcAddr,attachData);
    	 break;
      case 0xf1:
      case 0x07:
         SendVer(srcAddr,attachData);
         break;
      default:
         SendCmdError(srcAddr,ErrCode_UnKnowCmd,rxFrame->Data,5);
         break;
   }

}


void AnalogDeal()
{
   int i;
   uint16 chVal=0;
   uint32 rawVal;
   for(i=0;i<ChannelCount;i++)
   {

     if(!ReadChannelVal(i,&chVal)) continue;
     if(chVal==0xffff)continue;
#ifdef  DebugRawDate
     if(i==0&&(chVal>0x0728||chVal<0x720))
     {
    	 Serial_Send(0xff);
    	 Serial_Send(0xff);
    	 Serial_Send((uint8)(chVal>>8));
    	 Serial_Send((uint8)(chVal));
     }
#endif

     VoltCalcer_AddValue(calcers+i,chVal);

     if(calcers[i].PointCount==8000)
     {

        rawVal=CalcAcVal(calcers+i);
        if(rawVal<14)
        {
        	rawVal=0;
        }
        ACValues[i]=(rawVal*Coeff[i])>>12;
        if(ACValues[i]>50)
        {
          ACValues[i]|=0x8000;
        }
        VoltCalcer_Reset(calcers+i);
     }
   }

}
void CalcSum(DataFrame * frame)
{
	int i;
	uint16 sum=0;
	for(i=2;i<frame->Count;i++)
	{
		sum+=frame->Data[i];
	}
	DataFrame_Write(frame,&sum,2);
}


void ReWriteDataFrameLength(DataFrame *frame)
{
	uint16 len =frame->Count-2;
	frame->Data[0]=len&0xff;
	frame->Data[1]= len>>8;
}
void SendVer(uint8 dstAddr,uint8 *attachData)
{
  DataFrame df;
  uint8 buf[16];
  uint16 bytesCount;
  df.Data=buf;
  df.Capacity=16;
  df.Count=0;
  DataFrame_Write(&df,&bytesCount,2);
  DataFrame_Write(&df,&devAddr,1);
  DataFrame_Write(&df,&dstAddr,1);
  DataFrame_WriteByte(&df,0x07);
  DataFrame_Write(&df,&VerMessage,6);
  CalcSum(&df);
  ReWriteDataFrameLength(&df);
  SendDataFrame(&df);
}
void SendFactroyInfo(uint8 dstAddr,uint8 *attachData)
{
  DataFrame df;
  uint8 buf[32];
  uint16 bytesCount;
  df.Data=buf;
  df.Capacity=16;
  df.Count=0;

  DataFrame_Write(&df,&bytesCount,2);
  DataFrame_Write(&df,&devAddr,1);
  DataFrame_Write(&df,&dstAddr,1);
  DataFrame_WriteByte(&df,0xe4);
  DataFrame_WriteByte(&df,attachData[0]);
  DataFrame_Write(&df,FactoryInfo+(attachData[0]-0x50)*0x10,16);

  CalcSum(&df);
  ReWriteDataFrameLength(&df);
  SendDataFrame(&df);
}
void SetFactroyInfo(uint8 dstAddr,uint8 *attachData)
{
  DataFrame df;
  uint8 buf[16];
  uint16 bytesCount;
  df.Data=buf;
  df.Capacity=16;
  df.Count=0;
  uint8 saveRet;
  uint8 i;
  uint8 *dst=FactoryInfo+(attachData[0]-0x50)*0x10;
  for(i=0;i<16;i++)
  {
	  dst[i]=attachData[i+1];
  }
  UpdateCoeff();
  saveRet=SaveInfo(FactoryInfo,64);

  DataFrame_Write(&df,&bytesCount,2);
  DataFrame_Write(&df,&devAddr,1);
  DataFrame_Write(&df,&dstAddr,1);
  DataFrame_WriteByte(&df,0xe2);
  DataFrame_WriteByte(&df,attachData[0]);
  DataFrame_WriteByte(&df,saveRet);
  CalcSum(&df);
  ReWriteDataFrameLength(&df);
  SendDataFrame(&df);
}
void SendAnalog(uint8 dstAddr,uint8 * attachData)
{
  DataFrame df;
  uint8 buf[64];
  uint16 bytesCount;
  df.Data=buf;
  df.Capacity=32;
  df.Count=0;
  DataFrame_Write(&df,&bytesCount,2);
  DataFrame_Write(&df,&devAddr,1);
  DataFrame_Write(&df,&dstAddr,1);
  DataFrame_WriteByte(&df,Cmd_Analog);
  if(*attachData==ChNoAll)
  {
        DataFrame_WriteByte(&df,ChNoAll);

        DataFrame_Write(&df,ACValues,ChannelCount*2);
  }
  else
  {
      DataFrame_Write(&df,attachData,1);
      DataFrame_Write(&df,ACValues+attachData[0],2);

  }
  CalcSum(&df);
  ReWriteDataFrameLength(&df);
  SendDataFrame(&df);
}

void SendDigit(uint8 dstAddr,uint8 * attachData)
{
  DataFrame df;
  uint8 buf[16];
  uint16 bytesCount;
  df.Data=buf;
  df.Capacity=16;
  df.Count=0;
  DataFrame_Write(&df,&bytesCount,2);
  DataFrame_Write(&df,&devAddr,1);
  DataFrame_Write(&df,&dstAddr,1);
  DataFrame_WriteByte(&df,Cmd_Digit);
  DataFrame_WriteByte(&df,ChNoAll);
  DataFrame_Write(&df,DigitValues,4);
  CalcSum(&df);
  ReWriteDataFrameLength(&df);
  SendDataFrame(&df);
}

void SendCmdError(uint8 dstAddr,uint8 errCode,void *errData,uint8 errDataLen)
{
  DataFrame df;
  uint8 buf[16];
  uint16 bytesCount;
  df.Data=buf;
  df.Capacity=16;
  df.Count=0;
  DataFrame_Write(&df,&bytesCount,2);
  DataFrame_Write(&df,&devAddr,1);
  DataFrame_Write(&df,&dstAddr,1);
  DataFrame_WriteByte(&df,Cmd_Error);
  DataFrame_Write(&df,&errCode,1);
  DataFrame_Write(&df,errData,errDataLen);
  CalcSum(&df);
  ReWriteDataFrameLength(&df);
  SendDataFrame(&df);
}
